home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CColorBitMap / CColorBitMapPane.cp < prev    next >
Encoding:
Text File  |  1994-11-30  |  5.5 KB  |  280 lines  |  [TEXT/KAHL]

  1. /***************************************
  2.  "CColorBitMapPane.cp"
  3.  
  4.  by John A. Love, III [Ph.D. student]
  5.  
  6.  using Symantec's "THINK C / C++", v 6/7
  7.  based on Symantec's "Art Class"
  8.  ***************************************/
  9.  
  10.  
  11.  
  12.  
  13. #include <Global.h>
  14. #include <LongQD.h>
  15. #include <TCLUtilities.h>
  16.  
  17. #include "CColorBitMap.h"
  18. #include "CColorBitMapPane.h"
  19.  
  20.  
  21.  
  22. void    CColorBitMapPane::IColorBitMapPane (CView *anEnclosure,
  23.                                             CBureaucrat *aSupervisor,
  24.                                             short aWidth, short aHeight,
  25.                                             short aHEncl, short aVEncl,
  26.                                             SizingOption aHSizing,
  27.                                             SizingOption aVSizing,
  28.                                             LongRect *aBounds,
  29.                                             CColorBitMap *aBitMap,
  30.                                             Boolean makePort)
  31. {
  32.         Rect            globalBoundsR;
  33.         GDHandle        currMaxDevice;
  34.         RgnHandle        desktop;
  35.         
  36.         
  37.     CPanorama::IPanorama( anEnclosure, aSupervisor,
  38.                           aWidth, aHeight,
  39.                           aHEncl, aVEncl,
  40.                           aHSizing, aVSizing );
  41.     
  42.     bounds = *aBounds;
  43.     position.h = bounds.left;
  44.     position.v = bounds.top;
  45.     
  46.     itsBitMap = NULL;
  47.     bitsUnderPane = NULL;
  48.     gdOption = kDeepestScreen;
  49.     
  50.     /* Since FrameToGlobalR accesses CPane's hOrigin & vOrigin: */
  51.     CPane::Prepare();
  52.     
  53.     FrameToGlobalR( aBounds, &globalBoundsR );
  54.  
  55.     if ( !gSystem.hasColorQD )
  56.     {
  57.         currentDepth = 1;
  58.     }
  59.     else
  60.     {        
  61.         currMaxDevice = GetScreenDevice( &globalBoundsR );
  62.         if (currMaxDevice != nil)
  63.             currentDepth = (**( (**currMaxDevice).gdPMap )).pixelSize;
  64.         else
  65.             FailOSErr( NilGDeviceError );
  66.                     
  67.     }    /* has Color Quickdraw */
  68.     
  69.     if (aBitMap == NULL)
  70.     {
  71.         TRY
  72.         {
  73.             aBitMap = new (CColorBitMap);
  74.             /*
  75.                 IColorBitMap calls ForceNextPrepare().
  76.                 See other comments within "CColorBitMap.h":
  77.             */
  78.             aBitMap->IColorBitMap( (short) (aBounds->right - aBounds->left),
  79.                                    (short) (aBounds->bottom - aBounds->top),
  80.                                    makePort );
  81.             itsBitMap = aBitMap;
  82.         }
  83.         CATCH
  84.         {
  85.             ForgetObject( aBitMap );
  86.         }
  87.         ENDTRY;
  88.         
  89.      /*
  90.      ** I "roll my own" bounds within IColorBitMap:
  91.       ** itsBitMap->SetBoundsOrigin( aBounds->left, aBounds->top );
  92.       */
  93.       
  94.     }
  95.     
  96.     else    itsBitMap = aBitMap;
  97.  
  98.     TRY
  99.     {
  100.         bitsUnderPane = new (CColorBitMap);
  101.         bitsUnderPane->IColorBitMap( (short) (aBounds->right - aBounds->left),
  102.                                      (short) (aBounds->bottom - aBounds->top),
  103.                                      makePort );
  104.     }
  105.     CATCH
  106.     {
  107.         ForgetObject( bitsUnderPane );        /* Can't have one ...      */
  108.         ForgetObject( itsBitMap );            /* ... without the other. */
  109.     }
  110.     ENDTRY;
  111.     
  112.     autoRefresh = FALSE;
  113.     
  114. }    /* IColorBitMapPane */
  115.  
  116.  
  117.  
  118. /* OVERRIDE: */
  119. void    CColorBitMapPane::Dispose (void)
  120. {
  121.  
  122.     ForgetObject( bitsUnderPane );
  123.  
  124.     CBitMapPane::Dispose();
  125.     
  126. }    /* Dispose */
  127.  
  128.  
  129.  
  130. /* OVERRIDE: */
  131. void    CColorBitMapPane::Draw (Rect *area)
  132. {
  133.     /* Shhhh!! - don't say "macBitMap": */
  134.     
  135.         LongRect        theLBounds, lArea;
  136.         Rect            theSBounds;
  137.     
  138.     
  139.     if (itsBitMap != NULL)
  140.     {
  141.         if ( BitMapsNeedUpdating() )
  142.         {
  143.             ((CColorBitMap*) itsBitMap)->Update();
  144.             if (bitsUnderPane)        bitsUnderPane->Update();
  145.         }
  146.         
  147.         itsBitMap->GetBounds( &theLBounds );
  148.         LongToQDRect( &theLBounds, &theSBounds );
  149.         SectRect( area, &theSBounds, area );
  150.         
  151.         QDToFrameR( area, &lArea );
  152.         itsBitMap->CopyFrom( &lArea, &lArea, NULL );
  153.     }
  154.     
  155. }    /* Draw */
  156.  
  157.  
  158.  
  159.  
  160. Boolean        CColorBitMapPane::BitMapsNeedUpdating (void)
  161. {
  162.         LongRect    theBoundsRect;
  163.         Rect        globalBoundsR;
  164.         GDHandle    newMaxDevice;
  165.         short        newDepth;
  166.         
  167.         
  168.     if ( !gSystem.hasColorQD )
  169.     {
  170.         return    (FALSE);
  171.     }
  172.     else
  173.     {
  174.         Prepare();
  175.         
  176.         itsBitMap->GetBounds( &theBoundsRect );
  177.         FrameToGlobalR( &theBoundsRect, &globalBoundsR );
  178.         
  179.         newMaxDevice = GetScreenDevice( &globalBoundsR );
  180.         if (newMaxDevice == nil)
  181.         {
  182.             return    (FALSE);    /* May be literally off the screen. */
  183.         }
  184.         else
  185.         {
  186.             newDepth = (**( (**newMaxDevice).gdPMap )).pixelSize;
  187.             if (newDepth > currentDepth)
  188.             {
  189.                 currentDepth = newDepth;
  190.                 return    (TRUE);
  191.             }
  192.             else
  193.             {
  194.                 return    (FALSE);
  195.             }
  196.             
  197.         }    /* newMaxDevice ≠ nil */
  198.         
  199.     }    /* has Color Quickdraw */
  200.     
  201. }    /* BitMapsNeedUpdating */
  202.  
  203.  
  204.  
  205. GDHandle    CColorBitMapPane::GetScreenDevice (Rect *globalRect)
  206. {
  207.         RgnHandle        desktop;
  208.         long            area, maxArea;
  209.         GDHandle        device, result = nil;
  210.         Rect            intersection;
  211.  
  212.  
  213.     /* Different screen options require different algorithms: */
  214.     
  215.     if (gdOption == kDeepestScreen)
  216.     {
  217.         result = GetMaxDevice( globalRect );
  218.     }
  219.     
  220.     else if (gdOption == kLargestAreaScreen)
  221.     {
  222.         /* Get a Handle to the first GDevice in the GDevice list: */
  223.         device = GetDeviceList();
  224.  
  225.         /* Keep looping until all GDevices have been checked: */
  226.         maxArea = 0;
  227.         while (device != nil)
  228.         {
  229.             if ( TestDeviceAttribute( device, screenDevice ) )
  230.             {
  231.                 if ( TestDeviceAttribute( device, screenActive ) )
  232.                 {
  233.                     /* Do screen and passed Rect intersect? */
  234.                     if ( SectRect( globalRect, &((**device).gdRect), &intersection ) )
  235.                     {
  236.                         /* Yup, so calculate the interection: */
  237.                         area = (long)(intersection.right - intersection.left) * 
  238.                                (long)(intersection.bottom - intersection.top);
  239.                         
  240.                         /* Keep track of largest interection area found so far: */
  241.                         if (area > maxArea)
  242.                         {
  243.                             result = device;
  244.                             maxArea = area;
  245.                         }
  246.  
  247.                     }    /* if SectRect ... */
  248.  
  249.                     device = GetNextDevice( device );
  250.             
  251.                 }    /* screenActive */
  252.             
  253.             }    /* screenDevice */
  254.         
  255.         }    /* while */
  256.         
  257.     }    /* else: kLargestAreaScreen */
  258.     
  259.     if (result == nil)
  260.     {
  261.         /*
  262.         ** We're literally OFF the screen, so effect a DeviceOption
  263.         ** = "kLargestAreaScreen" based on the total Desktop region.
  264.         ** Change the object's "gdOption" instance variable since
  265.         ** we may have passed "kLargestAreaScreen":
  266.         */
  267.         desktop = GetGrayRgn();
  268.         result = GetMaxDevice( &(**desktop).rgnBBox );
  269.         if (result != nil)        gdOption = kDeepestScreen;
  270.     }
  271.     
  272.     return    (result);
  273.  
  274. }    /* GetScreenDevice */
  275.  
  276.  
  277.  
  278.  
  279. /* end: "CColorBitMapPane.cp" */
  280.